package helpdesk;

/* This file interfaces with GridFS, which was mongo uses to store files.
 * Created by: John Eversole 08/1/2012
 */

import com.mongodb.*;
import com.mongodb.gridfs.GridFS;
import com.mongodb.gridfs.GridFSDBFile;
import com.mongodb.gridfs.GridFSInputFile;
import java.awt.Desktop;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

/*
 * This file was created to manage all of our file managing stuff with mongodb
 * Author: John Eversole
 */
public class GFS {

    // path to download the files to
    private static String path = System.getenv("APPDATA") + "\\HelpDesk\\";
    
    // makes a string upperCase
    public static String upperCase(String str)
    {
        return str.substring(0, 1).toUpperCase() + str.substring(1);
    }
    
    // this function assumes the filepath looks like C:\Users\Download\...\file.pdf
    public static String generateNewFileName(String filePath, String username)
    {
        
        String[] dirPath = filePath.split("\\\\");
        String[] file;
        
        // Ex: file.pdf
        // nameNoType = file
        // ext = pdf
        // newName = StevenFilePdf
        String nameNoType = "";
        String ext = "";
        String newName = "";
        
        file = dirPath[dirPath.length - 1].split("\\.");
        nameNoType = upperCase(file[0]);
        ext = upperCase(file[1]);
        newName = username + upperCase(nameNoType) + upperCase(ext);
        
        return newName;
    }
    
    // This function saves a file record with the attributes as listed in the parameters
    public static boolean saveFileRecord(String filename, boolean readStatus, String collect, DB db)
    {
        boolean success = false;
        
        try
        {
            DBCollection collection = db.getCollection(collect);
            FileRec temp = new FileRec(filename, readStatus);
            collection.insert(temp.toBasicDBObject());
        }
        catch (Exception e)
        {
            success = false;
        }
        
        return success;
    }
    
    // Retrieves a file record given the file name and what collection to look in
    public static BasicDBObject retrieveFileRecord(String filename, String collection, DB db)
    {
        BasicDBObject search = new BasicDBObject();
        
        search.put("filename", filename);
        BasicDBObject result = (BasicDBObject) db.getCollection(collection).findOne(search);
        
        return result;
    }
    
    // this function finds the db object with the given filename, and changes 
    // the read status to true
    public static boolean updateFileRecord(String filename, String collection, DB db)
    {
        boolean success = false;
        
        try
        {
            BasicDBObject query = new BasicDBObject();
            BasicDBObject updated = retrieveFileRecord(filename, collection, db);

            updated.append("read", true);
            query.put("filename", filename);

            db.getCollection(collection).update(query, updated);
            success = true;
        }
        catch (Exception e)
        {
            success = false;
        }
        
        return success;        
    }
    
    // stores a file in mongo given the filepath and the username of the user
    // who submitted it
    public static String saveFile(File fileObj, String username, String collection, DB db) 
    {
        String newFileName = "";
        
        try
        {
            newFileName = generateNewFileName(fileObj.getAbsolutePath(), username);
            if(!fileObj.exists())
            {
                System.out.println("File does not exist.");
                return newFileName;
            }
            
            // create a new GridFS object
            GridFS gfsObj = new GridFS(db, collection);
            // load the file into a GFS input file
            GridFSInputFile gfsFile = gfsObj.createFile(fileObj);
            // set the filename and save
            gfsFile.setFilename(newFileName);
            gfsFile.save();
            // create a record for the file as well
            saveFileRecord(newFileName, false, collection, db);
        }
        catch (IOException e)
        {
            newFileName = "";
            System.out.println("File failed to save, IOException.");
        }
       
        return newFileName;
    }
    
    // this function retrives and opens a given file
    public static boolean retrieveFile(String newFileName, String collection, DB db)
    {
        boolean success = false;
        String fullPath;
        
        try
        {
            // find the image in the db
            GridFS gfsObj = new GridFS(db, collection);
            GridFSDBFile imageForOutput = gfsObj.findOne(newFileName);
            // create a path to download to
            fullPath = path + newFileName + "." + newFileName.substring(newFileName.length() - 3).toLowerCase();
            // save it there
            imageForOutput.writeTo(fullPath);
            // mark file as read
            updateFileRecord(newFileName, collection, db);
            // open the file
            Desktop.getDesktop().open(new File(fullPath));
            success = true;
        }
        catch (Exception e)
        {
            System.out.println("File failed to load.");
        }
        
        return success;
    }
    
    // retrives all documents in the db given a collection and db connection
    public static ArrayList<FileRec> retrieveAllDocs(String collect, DB db)
    {
        ArrayList<FileRec> fileRecs = new ArrayList();
        
        // get the objects in the given collection
        DBCollection collection = db.getCollection(collect);
        DBCursor cursor = collection.find();
        DBObject temp;
        String tempStr;
        FileRec newFR = new FileRec();
        
        // for each result
        while(cursor.hasNext())
        {
            temp = cursor.next();
            // map to a FileRec obj
            newFR.filename = temp.get("filename").toString();
            tempStr = temp.get("read").toString();
            newFR.read = Boolean.getBoolean(tempStr);
            // add it a list to be returned
            fileRecs.add(newFR);
        }

        return fileRecs;
    }
}
